#include <iostream>
#include <vector>
#include <chrono>
#include <string>
#include <fstream>
#include <numeric>

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "tracker4y/track_4y_500fps.h"

using namespace std;
using namespace cv;

cv::Rect_<float> location(0,0,0,0);

int main(int argc, char* argv[])
{

    Track4y500FPS trackerfc;
//    std::string sequence = argv[1];
    std::string sequence = "/home/lx/test_data/2023-01.mp4";

    std::string video_base_path = "..";
    std::string pattern_jpg = sequence + "/*.jpeg";//jpeg png
    std::string txt_base_path = sequence + "/groundtruth.txt";

    cv::Mat image;
    cv::Mat video_image;
    cv::Mat re(768, 1024, CV_8UC3);
    cv::Mat image_roi;
    cv::Rect_<float> click_roi;
    cv::Mat image_click_roi;
    std::vector<cv::Rect_<float>> result_rects;
    int64 tic, toc;
    double time = 0;
    bool show_visualization = true;
    bool is_save = false;
    float ap =0;
    long time2 = 0;
    int num = 0;

    bool first_frame = true;
    int re_cnt = 0;
    int verify_cnt = 0;
    int global_detect_cnt = 0;
    int track_cnt = 0;
    int low_psr_cnt = 0;
    int frame = 0;
    int long_time = 0;
    float scores=0;

    cv::VideoCapture capture(sequence);

    // //检测是否正常打开:成功打开时，isOpened返回ture
    if (!capture.isOpened())
    {
        std::cout << "fail to open!"<<std::endl;
        return -1;
    }

    while (capture.read(image))
    {
        ++frame;

        if (first_frame){
            tic = cv::getTickCount();
            cv::Rect2i selectRoi = selectROI("image", image, false, false);
            if (selectRoi.empty())
            {
                // std::cout << "catch is empty!!!!!!" << std::endl;
                first_frame = true;
                continue;
            }
            location.x = selectRoi.x;
            location.y = selectRoi.y;
            location.width = selectRoi.width;
            location.height = selectRoi.height;

            cout << location.x << " " << location.y << " "
                 << location.width << " " << location.height << endl;

            trackerfc.init(image, location);
            first_frame = false;
        }
        else {
            auto x1 = cv::getTickCount();
            location = trackerfc.update(image,scores);
            auto x2 = cv::getTickCount();
            cout << (x2 - x1) << endl;
            num++;
            time2 += (x2 - x1);

            if(scores <0.25){
                low_psr_cnt ++;
                if(low_psr_cnt>=5){
                }
            }
            else{
                low_psr_cnt=0;
            }
        }

        verify_cnt++;

        result_rects.push_back(location);

        if (show_visualization) {
            cv::putText(image,std::to_string(frame), cv::Point(20, 40), 6, 1, cv::Scalar(0, 255, 255), 2);
            cv::putText(image, std::to_string((int)ap), cv::Point(200, 40), 6, 1, cv::Scalar(0, 255, 255), 2);
            cv::putText(image, std::to_string(scores), cv::Point(400, 40), 6, 1, cv::Scalar(0, 255, 255), 2);
            cv::rectangle(image, location, cv::Scalar(0, 255, 0), 2);
            int center_x = (int)(location.x + location.width/2);
            int center_y = (int)(location.y + location.height/2);
            cv::circle(image, cv::Point(center_x, center_y), 3, (0, 0, 255), 1);

            cv::imshow("show", image);

            char key = cv::waitKey(3);
            if (key == 27 || key == 'q' || key == 'Q')
                break;
            if(key == 'p')
            {
                first_frame = true;
                cout << "******************" << endl;
                continue;
            }

        }
    }
    time = time / double(cv::getTickFrequency());
    double fps = double(result_rects.size()) / time;

    cv::destroyAllWindows();

    double cost_time = (double)time2 / (double)num;
    std::cout << "cost time:" << cost_time/1000000.0 << "ms." << '\t' << "FPS:" << (int)(1000/(cost_time/1000000.0)) << endl;

    return 0;
}
